package nus.mtech.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;

import nus.mtech.bill.Account;
import nus.mtech.bill.AccountManager;
import nus.mtech.bill.Bill;
import nus.mtech.bill.BillManager;
import nus.mtech.call.Call;
import nus.mtech.call.CallManager;
import nus.mtech.customer.Complaint;
import nus.mtech.customer.ComplaintManager;
import nus.mtech.customer.Customer;
import nus.mtech.customer.CustomerManager;
import nus.mtech.rate.RateManager;
import nus.mtech.subscription.Subscription;
import nus.mtech.subscription.SubscriptionManager;
import nus.mtech.user.AuthenticationManager;
import nus.mtech.user.User;

/**
 * <p>Title</p>
 * <p>Copyright (c) 2011 NUS ISS.  All rights reserved. </p>
 * @author Jiang Hao Min
 * @version 1.0
 *
 * <p align='left'>
 * <table border='1' width='80%'>
 *   <tr>
 *     <th colspan='4'>Change History</th>
 *   </tr>
 *   <tr>
 *     <td><u>Version</u></td>
 *     <td><u>Name</u></td>
 *     <td><u>Date</u></td>
 *     <td><u>Remarks</u></td>
 *   </tr>
 *   <tr>
 *     <td>1.0</td>
 *     <td>Jiang Hao Min</td>
 *     <td>Mar 21, 2011</td>
 *     <td>Creation of the class.</td>
 *   </tr>
 * </table>
 * </p>
 */

public class ImpDataUtil {
	private final static String FILE_SEP = File.separator;
	private final static String PROJECT_DIR = System.getProperty("user.dir");
	
	public static void LoadData() throws Exception{
		//IOException, ClassNotFoundException
		File file = null;
		String inputPath = PROJECT_DIR + FILE_SEP + "data";
		
		String inputFile = inputPath + FILE_SEP + "rates.txt";
		file = new File(inputFile);
		if(file.exists()){
			RateManager.getRateManagerInstance().loadRates();
		}
		
		inputFile = inputPath + FILE_SEP + "Customer.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForCustomer(inputFile);
		}
		
		inputFile = inputPath + FILE_SEP + "CustomerAccount.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForCustomerAccount(inputFile);
		}

		inputFile = inputPath + FILE_SEP + "Complaint.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForComplaint(inputFile);
		}
		
		inputFile = inputPath + FILE_SEP + "Subscription.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForSubscription(inputFile);
		}
		
		inputFile = inputPath + FILE_SEP + "Bill.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForBill(inputFile);
		}
		
		inputFile = inputPath + FILE_SEP + "Call.txt";
		file = new File(inputFile);
		if(file.exists()){
			LoadForCall(inputFile);
		}

		inputFile = inputPath + FILE_SEP + "SeqNo.dat";
		file = new File(inputFile);
		if(file.exists()){
			LoadForSeqNo(inputFile);
		}
		
		//add by Guo Yu
		inputFile = inputPath + FILE_SEP + "account.txt";
		file = new File(inputFile);
		if(file.exists()){
			LoadForAccount(inputFile);
		}
		
	}
	
	private static void LoadForSeqNo(String inputFile) throws IOException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			int customerId = ois.readInt();
			int accountId = ois.readInt();
			int complaintId = ois.readInt();
			int billId = ois.readInt();
			
			System.out.println("Initial Loading: customerId=" + customerId + ", complaintId=" + complaintId + ", billId=" + billId + ", accountId=" + accountId);
			
			CustomerManager.getCustomerManagerInstance().setCustomerId(customerId);
			AccountManager.getInstance().setAccountUID(accountId);
			ComplaintManager.getComplaintManagerInstance().setComplaintId(complaintId);
			BillManager.getBillManagerInstance().setBillId(billId);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void LoadForCustomer(String inputFile) throws IOException, ClassNotFoundException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			HashMap<String, Customer> map = (HashMap<String, Customer>)ois.readObject();
			CustomerManager.getCustomerManagerInstance().setCustomerMap(map);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
/*	
	private static void LoadForCustomer(String inputFile) throws IOException{
		FileReader fr = null;
		BufferedReader br = null;
		
		try{
			fr = new FileReader(inputFile);
			br = new BufferedReader(fr);
			
			String line = "";
			int index = 0;
			boolean isFirstRow = true;
			while((line = br.readLine()) != null){
				if(isFirstRow){
					isFirstRow = false;
				}else{
					String[] str = line.split("\t");
					Customer customer = new Customer();
					index = 0;
					
					customer.setAccountNo(trim(str[index++]));
					customer.setCustName(trim(str[index++]));
					customer.setCustNRIC(trim(str[index++]));
					customer.setCustTelNo(trim(str[index++]));
					customer.setCustBillingAddr(trim(str[index++]));
					customer.setCustInterests(trim(str[index++]));
					customer.setCustStatus(Boolean.parseBoolean(trim(str[index++])));
					
					CustomerManager.getCustomerManagerInstance().addNewCustomer(customer);
				}
			}
		}finally{
			if(null != br){
				br.close();
			}
			if(null != fr){
				fr.close();
			}
		}
	}
*/
	
	@SuppressWarnings("unchecked")
	private static void LoadForCustomerAccount(String inputFile) throws IOException, ClassNotFoundException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			HashMap<String, Account> map = (HashMap<String, Account>)ois.readObject();
			AccountManager.getInstance().setAccountMap(map);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void LoadForComplaint(String inputFile) throws IOException, ClassNotFoundException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			Map<String, ArrayList<Complaint>> map = (Map<String, ArrayList<Complaint>>)ois.readObject();
			ComplaintManager.getComplaintManagerInstance().setComplaintMap(map);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void LoadForSubscription(String inputFile) throws IOException, ClassNotFoundException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			HashMap<String, ArrayList<Subscription>> map = (HashMap<String, ArrayList<Subscription>>)ois.readObject();
			SubscriptionManager.getSubscriptionManagerInstance().setMapOfSubscriptions(map);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void LoadForBill(String inputFile) throws IOException, ClassNotFoundException{
		InputStream is = null;
		ObjectInputStream ois = null;
		
		try{
			is = new FileInputStream(inputFile);
			ois = new ObjectInputStream(is);
			
			HashMap<String, ArrayList<Bill>> map = (HashMap<String, ArrayList<Bill>>)ois.readObject();
			BillManager.getBillManagerInstance().setMapOfBills(map);
			
			HashMap<String, Date> flagMap = (HashMap<String, Date>)ois.readObject();
			BillManager.getBillManagerInstance().setMonthlyBillFlagMap(flagMap);
		}finally{
			if(null != ois){
				ois.close();
			}
			if(null != is){
				is.close();
			}
		}
	}
	
	private static void LoadForCall(String inputFile) throws IOException{
		FileReader fr = null;
		BufferedReader br = null;
		ArrayList<Call> list = new ArrayList<Call>();
		
		try{
			fr = new FileReader(inputFile);
			br = new BufferedReader(fr);
			
			String line = "";
			int index = 0;
			boolean isFirstRow = true;
			while((line = br.readLine()) != null){
				if(isFirstRow){
					isFirstRow = false;
				}else{
					String[] str = line.split("\t");
					index = 0;
					
					String accountNo = trim(str[index++]);
					int callType = Integer.parseInt(trim(str[index++]));
					String numFrom = trim(str[index++]);
					String numTo = trim(str[index++]);
					Date callDate = DateUtil.parseDate(trim(str[index++]), DateUtil.DATE_FORMAT);
					int callDuration = Integer.parseInt(trim(str[index++]));
					
					Call call = new Call(callType, numFrom, numTo, callDate, callDuration, accountNo);
					list.add(call);
				}
			}
		}finally{
			if(null != br){
				br.close();
			}
			if(null != fr){
				fr.close();
			}
		}
		
		if(0 < list.size()){
			CallManager.getCallManagerInstance().populateCallMap(list);
		}
	}
	
	private static void LoadForAccount(String inputFile) throws IOException{
		FileReader fr = null;
		BufferedReader br = null;
		ArrayList<User> list = new ArrayList<User>();
		
		try{
			fr = new FileReader(inputFile);
			br = new BufferedReader(fr);
			
			String line = "";
			int index = 0;
			boolean isFirstRow = true;
			while((line = br.readLine()) != null){
				if(isFirstRow){
					isFirstRow = false;
				}else{
					String[] str = line.split("\t");
					index = 0;
					
					String userId = trim(str[index++]);
					String password = trim(str[index++]);
					String role = trim(str[index++]);
					User user = new User(userId, password, role);
					list.add(user);
				}
			}
		}finally{
			if(null != br){
				br.close();
			}
			if(null != fr){
				fr.close();
			}
		}
		
		if(0 < list.size()){
			AuthenticationManager.getInstance().setUserList(list);
		}
	}

	private static String trim(String str){
		String returnStr = "";
		if(null != str){
			returnStr = str.trim();
		}
		return returnStr;
	}
}

